<?php

namespace app\common\logic\comic;

use app\admin\model\fa\Chapter;
use app\admin\model\fa\Comic;
use app\common\logic\BaseLogic;
use app\common\model\fa\comic\ChapterSource;
use fast\MinioServer;
use think\Db;

class ComicLogic extends BaseLogic
{
    /**
     * 导入漫画章节
     * @param $comicId
     * @param $zipPath
     * @param $importedDelete
     * @return bool
     */
    public function chapterImportZip($comicId, $zipPath, $importedDelete = false): bool
    {
        try {


            $comicModel = new Comic();
            $chapterModel = new Chapter();
            $sourceModel = new ChapterSource();

            $comic = $comicModel->find($comicId);

            if (!$comic) {
                throw new \Exception("漫画不存在");
            }

            //获取文件的真实路径
            if (!file_exists($zipPath)) {
                throw new \Exception("文件不存在");
            }

            $zipObject = new \ZipArchive();

            if (!$zipObject->open($zipPath)) {
                throw new \Exception('打开压缩文件失败');
            }

            //创建该漫画的文件夹
            $toPath = public_path(sprintf('uploads/comic/%s', $comicId));

            if (!file_exists($toPath)) {
                @mkdir($toPath, 0777, true);
            }

            //先删除一次该目录下的文件
            clean_folders($toPath);

            if ($zipObject->extractTo($toPath) === false) {
                throw new \Exception("解压文件失败");
            }

            $maxChapterNum = Chapter::where('comic_id', $comicId)->count();
            foreach (array_merge(array_filter(scandir($toPath), fn($value) => !in_array($value, ['.', '..', '__MACOSX']))) as $fold) {
                $maxChapterNum++;
                //目标文件夹
                $foldName = sprintf('%s/%s', $toPath, $fold);

                //扫描这个文件夹,上传到 minio
                if (!file_exists($foldName)) {
                    throw new \Exception('解压出错,文件不存在');
                }

                if (!is_dir($foldName)) {
                    throw new \Exception('压缩包内容有误,请检查');
                }


                $chapter = [];
                if ($foldList = scandir($foldName)) {
                    $foldList = array_filter($foldList, fn($value) => !in_array($value, ['.', '..']));
                    sort($foldList, SORT_NUMERIC);
                    foreach ($foldList as $item) {
                        if (!in_array($item, ['.', '..', '__MACOSX'])) {
                            //这个时候才处理,是文件
                            $filePath = realpath(sprintf('%s/%s', $foldName, $item));
                            if ($filePath !== false && is_file($filePath)) {
                                //上传到 monio
                                $rus = MinioServer::getInstance()->putObjectByFilePath($filePath);
                                $chapter[] = $rus['url'];
                                @unlink($filePath);
                            }
                            sleep(1);
                        }
                    }
                }

                if ($chapter) {
                    Db::startTrans();
                    $chapterId = $chapterModel->insertGetId(array(
                        'comic_id' => $comicId,
                        'title' => sprintf('第%s章', $maxChapterNum),
                        'thumb' => reset($chapter),
                        'intro' => '没有介绍',
                    ));
                    if (!$chapterId) {
                        throw new \Exception("章节处理失败");
                    }
                    //漫画资源
                    $insert = array_map(function ($item) use ($chapterId) {
                        return [
                            'chapter_id' => $chapterId,
                            'source' => $item,
                        ];
                    }, $chapter);
                    if (!$sourceModel->insertAll($insert)) {
                        throw new \Exception("资源处理失败");
                    }
                    Db::commit();
                }
            }

        } catch (\Throwable $exception) {
            Db::rollback();
            return $this->setMessage($exception->getMessage());
        } finally {
            if ($importedDelete) {
                @unlink($zipPath);
            }
        }
        return true;
    }

}